package com.itstyle.quartz.job;

import java.io.IOException;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
import java.util.UUID;

import com.alibaba.fastjson.JSONObject;
import com.itstyle.quartz.entity.JobLog;
import com.itstyle.quartz.service.IJobService;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

/**
 * Job 的实例要到该执行它们的时候才会实例化出来。每次 Job 被执行，一个新的 Job 实例会被创建。
 * 其中暗含的意思就是你的 Job 不必担心线程安全性，因为同一时刻仅有一个线程去执行给定 Job 类的实例，甚至是并发执行同一 Job 也是如此。
 *
 * @DisallowConcurrentExecution 保证上一个任务执行完后，再去执行下一个任务，这里的任务是同一个任务
 */
@DisallowConcurrentExecution
public class MyJob implements Job, Serializable {

    private static final long serialVersionUID = 1L;

    private static final Logger log = LoggerFactory.getLogger(MyJob.class);

    @Autowired
    private IJobService jobService;

    @Override
    public void execute(JobExecutionContext arg0) throws JobExecutionException {
        String uuid = UUID.randomUUID().toString();
        Long start = System.currentTimeMillis();
        log.info("定时任务开始>> uuid: {} job: {}", JSONObject.toJSONString(arg0.getJobDetail()));
        JobDetail jobDetail = arg0.getJobDetail();
        JobLog jobLog = new JobLog();
        jobLog.setJobName(jobDetail.getKey().getGroup()+"-"+jobDetail.getKey().getName());
        jobLog.setCreateTime(new Timestamp(System.currentTimeMillis()));
        try {
            String jobUrl = jobDetail.getJobDataMap().getString("jobUrl");
            jobLog.setJobUrl(jobUrl);
            if (StringUtils.isEmpty(jobUrl)) {
                log.info("任务结束 uuid : {} 执行失败原因 [jobUrl为空]", uuid);
                return;
            }
            String result = post(jobUrl);
            jobLog.setJobResult(result);
            jobLog.setJobStatus(0);
            if (!StringUtils.isEmpty(result)) {
                JSONObject data = JSONObject.parseObject(result);
                if ("1".equals(data.getString("code"))) {
                    jobLog.setJobStatus(1);
                }
            }
        } catch (Exception e) {
            log.error("任务执行异常", e);
        } finally {
            jobService.saveJobLog(jobLog);
        }

        log.info("定时任务结束>> uuid : {} 共耗时[" + (System.currentTimeMillis() - start) + "]毫秒", uuid);

    }

    /**
     * 发送HttpPost请求，参数为json字符串
     *
     * @param url
     * @return
     */
    public static String post(String url) {
        String result = null;
        CloseableHttpResponse response = null;
        try {
            HttpGet httpPost = new HttpGet(url);
            CloseableHttpClient httpclient = HttpClients.createDefault();
            log.info("调用接口参数 url {}", url);
            response = httpclient.execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            result = EntityUtils.toString(httpEntity);
            log.info("调用接口结果 result {}", result);
        } catch (Exception e) {
            log.error("调用接口异常", e.getMessage());
            result = e.getMessage();
        } finally {
            // 关闭CloseableHttpResponse
            if (response != null) {
                try {
                    response.close();
                } catch (IOException e) {
                    log.error(e.getMessage());
                }
            }
        }
        return result;
    }
}
